from loguru import logger
from pathlib import Path
from datetime import datetime
from typing import Optional
import sys
import os
import json


class Logger:
    """
    基于 loguru 的日志管理器类，提供统一的日志配置和管理功能
    """

    def __init__(self, name: str = "iot-mcp", level: str = "INFO"):
        self.name = name
        self.level = level
        self._configured = False
        self._setup_logger()

    def _setup_logger(self):
        """设置日志配置"""
        if self._configured:
            return

        # 移除默认处理器
        logger.remove()

        # 创建日志目录
        log_dir = Path("logs")
        log_dir.mkdir(exist_ok=True)

        # 日志格式
        log_format = (
            "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> - "
            "<blue>{extra[app_name]}</blue> - "
            "<level>{level}</level> - "
            "<cyan>{name}:{function}:{line}</cyan> - "
            "<level>{message}</level>"
        )

        # 控制台处理器 - INFO及以上级别
        logger.add(
            sys.stdout,
            format=log_format,
            level=self.level,
            filter=lambda record: record["extra"].get("app_name") == self.name,
            colorize=True,
        )

        # 主日志文件处理器 - level 及以上级别
        today = datetime.now().strftime("%Y-%m-%d")
        logger.add(
            log_dir / f"{today}.log",
            format=lambda record: self._custom_json_formatter(record),
            level=self.level,
            rotation="10 MB",
            retention="10 days",
            compression="zip",
            encoding="utf-8",
        )

        # 错误日志文件处理器 - ERROR及以上级别
        logger.add(
            log_dir / f"{today}-error.log",
            format=lambda record: self._custom_json_formatter(record),
            level="ERROR",
            rotation="5 MB",
            retention="10 days",
            compression="zip",
            encoding="utf-8",
        )

        # 绑定应用名称到logger上下文
        logger.bind(app_name=self.name)

        self._configured = True

    def _custom_json_formatter(self, record):
        """
        自定义JSON格式化器，只输出指定字段
        """
        try:
            # 构建caller信息
            caller: str = f"{record['name']}:{record['function']}:{record['line']}"
            
            # 构建自定义日志记录
            log_record = {
                "time": record['time'].timestamp(),
                "message": record['message'],
                "level": record['level'].name,
                "caller": caller,
                "thread": str(record['thread'].id) + '-' + record['thread'].name,
                "process": str(record['process'].id) + '-' + record['process'].name
            }
            
            # 如果有异常信息，添加到message中
            if record.get("exception"):
                log_record['message'] = f"{record['message']}\n{record['exception']}"
            
            return json.dumps(log_record, ensure_ascii=False)
        except Exception as e:
            # 如果格式化失败，返回简单的字符串格式
            return json.dumps({
                "time": str(record.get('time', 'unknown')),
                "level": str(record.get('level', {}).get('name', 'unknown')),
                "message": f"JSON formatting error: {str(e)}",
                "caller": f"{record.get('name', 'unknown')}:{record.get('function', 'unknown')}:{record.get('line', 'unknown')}",
                "thread": str(record.get('thread', {}).get('name', 'unknown')),
                "process": str(record.get('process', {}).get('name', 'unknown'))
            }, ensure_ascii=False)

    def get_logger(self):
        """获取绑定了应用名称的logger实例"""
        return logger.bind(app_name=self.name)

    def debug(self, message: str, *args, **kwargs):
        """记录调试信息"""
        logger.bind(app_name=self.name).debug(message, *args, **kwargs)

    def info(self, message: str, *args, **kwargs):
        """记录一般信息"""
        logger.bind(app_name=self.name).info(message, *args, **kwargs)

    def warning(self, message: str, *args, **kwargs):
        """记录警告信息"""
        logger.bind(app_name=self.name).warning(message, *args, **kwargs)

    def error(self, message: str, *args, **kwargs):
        """记录错误信息"""
        logger.bind(app_name=self.name).error(message, *args, **kwargs)

    def critical(self, message: str, *args, **kwargs):
        """记录严重错误信息"""
        logger.bind(app_name=self.name).critical(message, *args, **kwargs)

    def exception(self, message: str, *args, **kwargs):
        """记录异常信息（包含堆栈跟踪）"""
        logger.bind(app_name=self.name).exception(message, *args, **kwargs)


# 全局日志器实例
_global_logger: Optional[Logger] = None


def get_logger(name: str = "iot-mcp") -> Logger:
    """
    获取日志器实例

    Args:
        name: 日志器名称

    Returns:
        Logger实例
    """
    global _global_logger

    if _global_logger is None:
        _global_logger = Logger(name)

    return _global_logger


def setup_logging(log_level: str = "INFO", log_dir: str = "logs") -> Logger:
    """
    设置全局日志配置

    Args:
        log_level: 日志级别 ("TRACE", "DEBUG", "INFO", "SUCCESS", "WARNING", "ERROR", "CRITICAL")
        log_dir: 日志文件目录

    Returns:
        配置好的Logger实例
    """
    global _global_logger

    # 创建日志目录
    Path(log_dir).mkdir(exist_ok=True)

    # 设置环境变量
    os.environ["LOG_LEVEL"] = log_level.upper()
    os.environ["LOG_DIR"] = log_dir

    # 重新创建日志器
    _global_logger = Logger("iot-mcp")

    # 记录初始化完成
    _global_logger.info(
        f"🚀 日志系统初始化完成，日志级别: {log_level}，日志目录: {log_dir}"
    )

    return _global_logger


# 便捷函数 - 使用全局logger实例
def debug(message: str, *args, **kwargs):
    """记录调试信息"""
    get_logger().debug(message, *args, **kwargs)


def info(message: str, *args, **kwargs):
    """记录一般信息"""
    get_logger().info(message, *args, **kwargs)


def success(message: str, *args, **kwargs):
    """记录成功信息（loguru特有）"""
    logger.bind(app_name="iot-mcp-v2").success(message, *args, **kwargs)


def warning(message: str, *args, **kwargs):
    """记录警告信息"""
    get_logger().warning(message, *args, **kwargs)


def error(message: str, *args, **kwargs):
    """记录错误信息"""
    get_logger().error(message, *args, **kwargs)


def critical(message: str, *args, **kwargs):
    """记录严重错误信息"""
    get_logger().critical(message, *args, **kwargs)


def exception(message: str, *args, **kwargs):
    """记录异常信息（包含堆栈跟踪）"""
    get_logger().exception(message, *args, **kwargs)


def trace(message: str, *args, **kwargs):
    """记录追踪信息（loguru特有，比DEBUG更详细）"""
    logger.bind(app_name="iot-mcp-v2").trace(message, *args, **kwargs)


# 上下文管理器支持
def logger_context(**kwargs):
    """返回带有额外上下文的logger"""
    return logger.bind(app_name="iot-mcp-v2", **kwargs)


if __name__ == "__main__":
    # 测试日志功能
    setup_logging("DEBUG")

    # 基本日志测试
    trace("🔬 这是一条追踪信息")
    debug("🔍 这是一条调试信息")
    info("📝 这是一条普通信息")
    success("✅ 这是一条成功信息")
    warning("⚠️ 这是一条警告信息")
    error("❌ 这是一条错误信息")
    critical("🚨 这是一条严重错误信息")

    # 上下文测试
    context_logger = logger_context(user_id="12345", operation="test")
    context_logger.info("📊 带上下文的日志信息")

    # 异常测试
    try:
        1 / 0
    except Exception as e:
        exception("捕获到除零异常")

    print("\n🎉 loguru 日志系统测试完成！")
